{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Categorical Deep Q Network (C51)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import gym\n",
    "import numpy as np\n",
    "\n",
    "import torch\n",
    "import torch.optim as optim\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "from IPython.display import clear_output\n",
    "from matplotlib import pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from timeit import default_timer as timer\n",
    "from datetime import timedelta\n",
    "import math\n",
    "\n",
    "from utils.wrappers import *\n",
    "from agents.DQN import Model as DQN_Agent\n",
    "from utils.ReplayMemory import ExperienceReplayMemory\n",
    "\n",
    "from utils.hyperparameters import Config"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hyperparameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "config = Config()\n",
    "\n",
    "config.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "#epsilon variables\n",
    "config.epsilon_start = 1.0\n",
    "config.epsilon_final = 0.01\n",
    "config.epsilon_decay = 60000\n",
    "config.epsilon_by_frame = lambda frame_idx: config.epsilon_final + (config.epsilon_start - config.epsilon_final) * math.exp(-1. * frame_idx / config.epsilon_decay)\n",
    "\n",
    "#misc agent variables\n",
    "config.GAMMA=0.99\n",
    "config.LR=1e-4\n",
    "\n",
    "#memory\n",
    "config.TARGET_NET_UPDATE_FREQ = 1000\n",
    "config.EXP_REPLAY_SIZE = 100000\n",
    "config.BATCH_SIZE = 32\n",
    "\n",
    "#Learning control variables\n",
    "config.LEARN_START = 10000\n",
    "config.MAX_FRAMES=1000000\n",
    "\n",
    "#Nstep controls\n",
    "config.N_STEPS=1\n",
    "\n",
    "#Categorical Params\n",
    "config.ATOMS = 51\n",
    "config.V_MAX = 10\n",
    "config.V_MIN = -10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class CategoricalDQN(nn.Module):\n",
    "    def __init__(self, input_shape, num_actions, atoms=51):\n",
    "        super(CategoricalDQN, self).__init__()\n",
    "        \n",
    "        self.input_shape = input_shape\n",
    "        self.num_actions = num_actions\n",
    "        self.atoms = atoms\n",
    "\n",
    "        self.conv1 = nn.Conv2d(self.input_shape[0], 32, kernel_size=8, stride=4)\n",
    "        self.conv2 = nn.Conv2d(32, 64, kernel_size=4, stride=2)\n",
    "        self.conv3 = nn.Conv2d(64, 64, kernel_size=3, stride=1)\n",
    "\n",
    "        self.fc1 = nn.Linear(self.feature_size(), 512)\n",
    "        self.fc2 = nn.Linear(512, self.num_actions*self.atoms)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        x = F.relu(self.conv1(x))\n",
    "        x = F.relu(self.conv2(x))\n",
    "        x = F.relu(self.conv3(x))\n",
    "        x = x.view(x.size(0), -1)\n",
    "        x = F.relu(self.fc1(x))\n",
    "        x = self.fc2(x)\n",
    "\n",
    "        return F.softmax(x.view(-1, self.num_actions, self.atoms), dim=2)\n",
    "    \n",
    "    def feature_size(self):\n",
    "        return self.conv3(self.conv2(self.conv1(torch.zeros(1, *self.input_shape)))).view(1, -1).size(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Model(DQN_Agent):\n",
    "    def __init__(self, static_policy=False, env=None, config=None):\n",
    "        self.atoms = config.ATOMS\n",
    "        self.v_max = config.V_MAX\n",
    "        self.v_min = config.V_MIN\n",
    "        self.supports = torch.linspace(self.v_min, self.v_max, self.atoms).view(1, 1, self.atoms).to(config.device)\n",
    "        self.delta = (self.v_max - self.v_min) / (self.atoms - 1)\n",
    "\n",
    "        super(Model, self).__init__(static_policy, env, config)\n",
    "    \n",
    "    def declare_networks(self):\n",
    "        self.model = CategoricalDQN(self.num_feats, self.num_actions, atoms=self.atoms)\n",
    "        self.target_model = CategoricalDQN(self.num_feats, self.num_actions, atoms=self.atoms)\n",
    "        \n",
    "    def projection_distribution(self, batch_vars):\n",
    "        batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights = batch_vars\n",
    "\n",
    "        with torch.no_grad():\n",
    "            max_next_dist = torch.zeros((self.batch_size, 1, self.atoms), device=self.device, dtype=torch.float) + 1. / self.atoms\n",
    "            if not empty_next_state_values:\n",
    "                max_next_action = self.get_max_next_state_action(non_final_next_states)\n",
    "                max_next_dist[non_final_mask] = self.target_model(non_final_next_states).gather(1, max_next_action)\n",
    "                max_next_dist = max_next_dist.squeeze()\n",
    "\n",
    "            Tz = batch_reward.view(-1, 1) + (self.gamma**self.nsteps) * self.supports.view(1, -1) * non_final_mask.to(torch.float).view(-1, 1)\n",
    "            Tz = Tz.clamp(self.v_min, self.v_max)\n",
    "            b = (Tz - self.v_min) / self.delta\n",
    "            l = b.floor().to(torch.int64)\n",
    "            u = b.ceil().to(torch.int64)\n",
    "            l[(u > 0) * (l == u)] -= 1\n",
    "            u[(l < (self.atoms - 1)) * (l == u)] += 1\n",
    "            \n",
    "            offset = torch.linspace(0, (self.batch_size - 1) * self.atoms, self.batch_size).unsqueeze(dim=1).expand(self.batch_size, self.atoms).to(batch_action)\n",
    "            m = batch_state.new_zeros(self.batch_size, self.atoms)\n",
    "            m.view(-1).index_add_(0, (l + offset).view(-1), (max_next_dist * (u.float() - b)).view(-1))  # m_l = m_l + p(s_t+n, a*)(u - b)\n",
    "            m.view(-1).index_add_(0, (u + offset).view(-1), (max_next_dist * (b - l.float())).view(-1))  # m_u = m_u + p(s_t+n, a*)(b - l)\n",
    "\n",
    "        return m\n",
    "    \n",
    "    def compute_loss(self, batch_vars):\n",
    "        batch_state, batch_action, batch_reward, non_final_next_states, non_final_mask, empty_next_state_values, indices, weights = batch_vars\n",
    "\n",
    "        batch_action = batch_action.unsqueeze(dim=-1).expand(-1, -1, self.atoms)\n",
    "        batch_reward = batch_reward.view(-1, 1, 1)\n",
    "\n",
    "        current_dist = self.model(batch_state).gather(1, batch_action).squeeze()\n",
    "\n",
    "        target_prob = self.projection_distribution(batch_vars)\n",
    "          \n",
    "        loss = -(target_prob * current_dist.log()).sum(-1)\n",
    "        loss = loss.mean()\n",
    "\n",
    "        return loss\n",
    "    \n",
    "    def get_action(self, s, eps):\n",
    "        with torch.no_grad():\n",
    "            if np.random.random() >= eps:\n",
    "                X = torch.tensor([s], device=self.device, dtype=torch.float) \n",
    "                a = self.model(X) * self.supports\n",
    "                a = a.sum(dim=2).max(1)[1].view(1, 1)\n",
    "                return a.item()\n",
    "            else:\n",
    "                return np.random.randint(0, self.num_actions)\n",
    "            \n",
    "    def get_max_next_state_action(self, next_states):\n",
    "        next_dist = self.target_model(next_states) * self.supports\n",
    "        return next_dist.sum(dim=2).max(1)[1].view(next_states.size(0), 1, 1).expand(-1, -1, self.atoms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot Results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot(frame_idx, rewards, losses, sigma, elapsed_time):\n",
    "    clear_output(True)\n",
    "    plt.figure(figsize=(20,5))\n",
    "    plt.subplot(131)\n",
    "    plt.title('frame %s. reward: %s. time: %s' % (frame_idx, np.mean(rewards[-10:]), elapsed_time))\n",
    "    plt.plot(rewards)\n",
    "    if losses:\n",
    "        plt.subplot(132)\n",
    "        plt.title('loss')\n",
    "        plt.plot(losses)\n",
    "    if sigma:\n",
    "        plt.subplot(133)\n",
    "        plt.title('noisy param magnitude')\n",
    "        plt.plot(sigma)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training Loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1440x360 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "start=timer()\n",
    "\n",
    "env_id = \"PongNoFrameskip-v4\"\n",
    "env    = make_atari(env_id)\n",
    "env    = wrap_deepmind(env, frame_stack=False)\n",
    "env    = wrap_pytorch(env)\n",
    "model = Model(env=env, config=config)\n",
    "\n",
    "episode_reward = 0\n",
    "\n",
    "observation = env.reset()\n",
    "for frame_idx in range(1, config.MAX_FRAMES + 1):\n",
    "    epsilon = config.epsilon_by_frame(frame_idx)\n",
    "    \n",
    "    action = model.get_action(observation, epsilon)\n",
    "    prev_observation=observation\n",
    "    observation, reward, done, _ = env.step(action)\n",
    "    observation = None if done else observation\n",
    "\n",
    "    model.update(prev_observation, action, reward, observation, frame_idx)\n",
    "    episode_reward += reward\n",
    "\n",
    "    if done:\n",
    "        model.finish_nstep()\n",
    "        model.reset_hx()\n",
    "        observation = env.reset()\n",
    "        model.save_reward(episode_reward)\n",
    "        episode_reward = 0\n",
    "        \n",
    "        if np.mean(model.rewards[-10:]) > 19:\n",
    "            plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "            break\n",
    "\n",
    "    if frame_idx % 10000 == 0:\n",
    "        plot(frame_idx, model.rewards, model.losses, model.sigma_parameter_mag, timedelta(seconds=int(timer()-start)))\n",
    "\n",
    "model.save_w()\n",
    "env.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
